/*
 * <Pezad Platformer>
 * Copyright 2008 Shayne Riley
 * 
 * This file is part of <Pezad Platformer>.
 * 
 * <Pezad Platformer> is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * <Pezad Platformer> is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with <Pezad Platformer>.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * To contact the authors on questions or issues regarding the license,
 * you may send an email to <shayner@gmail.com> or write to
 * Shayne Riley / P.O. Box 1092 / McCook, NE 69001.
 */

#include "Graphics.h"
#include "SDLDelegate.h"
#include <iostream>
#include <SDL/SDL.h>

namespace pzdDisplay
{

Graphics& Graphics::getInstance()
{
	static Graphics instance;

	return instance;
}

Graphics::Graphics()
{
	init();
}

Graphics::~Graphics()
{
}

void Graphics::init()
{

	if(!pzd::SDLDelegate::getInstance().needSDL())
	{
		// Failure.
		std::cerr << __FILE__ << ": Could not initialize SDL Video. No "
			<< "Graphics available." << std::endl;
		return;
	}

	// check to see if screen already exists. If so, then remove the surface
	// after the new screen is in place.
	SDL_Surface *oldScreen = SDL_GetVideoSurface();

	// Set the screen to be used for graphics.
	SDL_Surface *screen = SDL_SetVideoMode(640, 480, 24, SDL_SWSURFACE);

	// If the old screen existed, then attempt to dispose the memory it used.
	if(oldScreen != NULL)
	{
		if(!(oldScreen->locked))
		{
			SDL_FreeSurface(oldScreen);
		}
		else
		{
			std::cerr << __FILE__ << ": Could not free old screen because it "
				<< "is locked. This is a memory leak." << std::endl;
		}
	}
	
	// If the new screen does not exist, then we're in trouble.
	if(screen == NULL)
	{
		std::cerr << __FILE__ << ": Unable to create screen. No visuals are "
			<< "available to the user." << std::endl;
	}
}

void Graphics::renderScene()
{
	SDL_UpdateRect(SDL_GetVideoSurface(), 0, 0, 0, 0);
}

void Graphics::drawImage(const ImageSDL * const image, int x, int y, int w,
		int h)
{
	SDL_Rect srcRect;
	
	srcRect.x = 0;
	srcRect.y = 0;
	srcRect.w = image->getWidth();
	srcRect.h = image->getHeight();

	SDL_Surface *screen = SDL_GetVideoSurface();

	SDL_Rect destRect;
	
	destRect.x = x;
	destRect.y = y;
	destRect.w = w;
	destRect.h = h;

	SDL_SoftStretch(image->getSurface(), &srcRect, screen, &destRect);
}

void Graphics::drawImage(const ImageSDL * const image, int x, int y)
{
	SDL_Rect srcRect;
	
	srcRect.x = 0;
	srcRect.y = 0;
	srcRect.w = image->getWidth();
	srcRect.h = image->getHeight();

	SDL_Surface *screen = SDL_GetVideoSurface();

	SDL_Rect destRect;
	
	destRect.x = x;
	destRect.y = y;
	destRect.w = image->getWidth();
	destRect.h = image->getHeight();

	SDL_BlitSurface(image->getSurface(), &srcRect, screen, &destRect);
}

} // namespace
